/**
 * KopsoxFramework
 * Copyright (C) 2010 Free Software Foundation, Inc. <http://fsf.org/>
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.kopsox.general.type;

import java.io.Serializable;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.Time;
import java.sql.Timestamp;

import org.kopsox.data.container.ValueContainer;
import org.kopsox.data.container.ValueEntity;
import org.kopsox.util.data.DateConverter;
import org.kopsox.util.data.impl.DateConverterImpl;

/**
 * @author Konrad Renner - 24.06.2010
 *
 */
public enum ValueTypeEnum implements ValueType{

        NULL(-1),
        STRING(0){
        	
			@Override
			public Object convert(String val) {
				return val;
			}

			@Override
			public Class<?> getClassFromType() {
				return String.class;
			}
        	
        },
        BOOLEAN(1){
                @Override
                public Object convert(String value) {
                        if (value != null) {
                                return Boolean.valueOf(value);
                        }
                        return null;
                }
                
                @Override
    			public Class<?> getClassFromType() {
    				return Boolean.class;
    			}
        },
        LONG(2){
                @Override
                public Object convert(String value) {
                        if (value == null || value.trim().length() == 0) {
                                return null;
                        }
                        try {
                            return new Long(value);
                        } catch (NumberFormatException e) {
                            return null;
                        }
                }
                
                @Override
    			public Class<?> getClassFromType() {
    				return Long.class;
    			}
        },
        FLOAT(3){
                @Override
                public Object convert(String value) {
                        if (value == null || value.trim().length() == 0) {
                                return null;
                        }
                        try {
                            return new Float(value);
                        } catch (NumberFormatException e) {
                            return null;
                        }
                }
                
                @Override
    			public Class<?> getClassFromType() {
    				return Float.class;
    			}
        },
        INTEGER(4){
                @Override
                public Object convert(String value) {
                        if (value == null || value.trim().length() == 0) {
                                return null;
                        }
                        try {
                            return new Integer(value);
                        } catch (NumberFormatException e) {
                            return null;
                        }
                }
                
                @Override
    			public Class<?> getClassFromType() {
    				return Integer.class;
    			}
        },
        DOUBLE(5){
                @Override
                public Object convert(String value) {
                        if (value == null || value.trim().length() == 0) {
                                return null;
                        }
                        try {
                            return new Double(value);
                        } catch (NumberFormatException e) {
                            return null;
                        }
                }
                
                @Override
    			public Class<?> getClassFromType() {
    				return Double.class;
    			}
        },
        BIGDECIMAL(6){
                @Override
                public Object convert(String value) {
                        if (value == null || value.trim().length() == 0) {
                                return null;
                        }
                        String newvalue = replaceSeperator(value);
                        try {
                            return new BigDecimal(newvalue.trim());
                        } catch (NumberFormatException e) {
                            return null;
                        }
                }
                
                @Override
    			public Class<?> getClassFromType() {
    				return BigDecimal.class;
    			}
                
                /**
                 * Changes the notation of a string, so that i can be convertet to a BigDecimal
                 * 
                 * @param value
                 * @return String
                 */
                public String replaceSeperator(String value) {
                        int indexOfComma = value.lastIndexOf(",");
                        int indexOfPoint = value.lastIndexOf(".");
                        String ret = value;
                        if (indexOfComma >= 0 || indexOfPoint >= 0) {
                                if (indexOfComma > indexOfPoint) {
                                        if (indexOfPoint > 0) {
                                                ret = value.replaceAll("\\.*", "");
                                        }
                                        ret = ret.replace(',', '.');
                                } else {
                                        if (indexOfComma > 0) {
                                                ret = value.replaceAll(",*", "");
                                        }
                                }
                        }
                        return ret;
                }
        },
        SQLDATE(7){
                @Override
                public Object convert(String value) {
                        return ValueTypeEnum.DATE_FORMATTER.convertToSQLDate(value);
                }
                
                @Override
    			public Class<?> getClassFromType() {
    				return java.sql.Date.class;
    			}
        },
        UTILDATE(8){
                @Override
                public Object convert(String value) {
                        return ValueTypeEnum.DATE_FORMATTER.convert(value);
                }
                
                @Override
    			public Class<?> getClassFromType() {
    				return java.util.Date.class;
    			}
        },
        TIME(9){
                @Override
                public Object convert(String value) {
                        return ValueTypeEnum.DATE_FORMATTER.convertToSQLTime(value);
                }
                
                @Override
    			public Class<?> getClassFromType() {
    				return java.sql.Time.class;
    			}
        },
        TIMESTAMP(10){
                @Override
                public Object convert(String value) {
                        try{
                        	return Timestamp.valueOf(value);
                        }catch(IllegalArgumentException e){
                        	java.util.Date converted = (java.util.Date)UTILDATE.convert(value);
                            return converted==null?null:new Timestamp(converted.getTime());
                        }
                }
                
                @Override
    			public Class<?> getClassFromType() {
    				return Timestamp.class;
    			}
        },
        BYTE(11){
                @Override
                public Object convert(String value) {
                        if (value == null || value.trim().length() == 0) {
                                return null;
                        }
                        try{
                                return new Byte(value);
                        }catch(NumberFormatException e){
                                return null;
                        }
                }
                
                @Override
    			public Class<?> getClassFromType() {
    				return Byte.class;
    			}
        },
        BIGINTEGER(12){
                @Override
                public Object convert(String value) {
                        if (value == null || value.trim().length() == 0) {
                                return null;
                        }
                        try {
                            return new BigInteger(value.trim());
                        } catch (NumberFormatException e) {
                            return null;
                        }
                }
                
                @Override
    			public Class<?> getClassFromType() {
    				return BigInteger.class;
    			}
        },
        SERIALIZEABLE(13){

			@Override
			public Class<?> getClassFromType() {
				return Serializable.class;
			}
        	
        },
        CONTAINER(14){

			@Override
			public Class<?> getClassFromType() {
				return ValueContainer.class;
			}
        	
        },
        ENTITY(15){

			@Override
			public Class<?> getClassFromType() {
				return ValueEntity.class;
			}
        	
        };
        
        private final int value;
        public static final DateConverter DATE_FORMATTER = new DateConverterImpl();
        
        private ValueTypeEnum(int value){
                this.value = value;
        }
        
        /* (non-Javadoc)
         * @see org.kopsox.general.type.Type#getTypeValue()
         */
        @Override
        public int getTypeValue() {
                return value;
        }
        
        /**
         * Creates an ValueTypeEnum with the help of an instance of an value
         * 
         * @param value
         * @return ValueTypeEnum
         */
        public final static ValueTypeEnum getTypeFromValue(Object value){
            if(value == null){
                    return NULL;
            }
            
            return getTypeFromClass(value.getClass());
        }
        
        /**
         * Creates a ValueTypeEnum with the help of the Class-Object from the value
         * 
         * @param value
         * @return ValueTypeEnum
         */
        public final static ValueTypeEnum getTypeFromClass(Class<?> value){
            if(value == null){
                    return NULL;
            }
            
            if(value.equals(String.class)){
                    return STRING;
            }else if(value.equals(Boolean.class)){
                    return BOOLEAN;
            }else if(value.equals(Integer.class)){
                    return INTEGER;
            }else if(value.equals(BigDecimal.class)){
                    return BIGDECIMAL;
            }else if(value.equals(java.sql.Date.class)){
                    return SQLDATE;
            }else if(value.equals(Time.class)){
                    return TIME;
            }else if(value.equals(Timestamp.class)){
                    return TIMESTAMP;
            }else if(value.equals(java.util.Date.class)){
                    return UTILDATE;
            }else if(value.equals(Long.class)){
                    return LONG;
            }else if(value.equals(Float.class)){
                    return FLOAT;
            }else if(value.equals(Integer.class)){
                    return INTEGER;
            }else if(value.equals(Double.class)){
                    return DOUBLE;
            }else if(value.equals(Byte.class)){
                    return BYTE;
            }else if(value.equals(BigInteger.class)){
                    return BIGINTEGER;
            }else{
                    return SERIALIZEABLE;
            }
        }
        
        /**
         * Converts a String to an other Type<br>
         * Following formats for Date & Time is allowed<br>
         * <ul>
         *  <li>Date-Formats are defined in the FormatsEnum</li>
         *  <li>Time-Formats are defined in the FormatsEnum</li>
         * </ul>
         * 
         * @param val - String
         * @return Object
         */
        @Override
        public Object convert(String val) {
                return null;
        }

		/* (non-Javadoc)
		 * @see org.kopsox.general.type.ValueType#getClassFromType()
		 */
		@Override
		public Class<?> getClassFromType() {
			return null;
		}
}
